package com.study.core.security;

import com.study.domain.MyUser;
import com.sun.org.apache.xpath.internal.SourceTree;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

/**
 * Spring securoty第二步：获取用户登录信息
 * Created by think on 2016/4/24.
 */
public class MyUserDetailService extends JdbcDaoImpl {
    private boolean enableAuthorities = true;
    private boolean enableGroups;
    private boolean usernameBasedPrimaryKey = true;

    private String myUsersByUsernameQuery = "select username,password,enabled,phone,age,nick,id from tb_users where username = ? limit 1";
    private String myAuthority = "select role_name as authority from tb_role where id in (select role_id from tb_users_role where username = ?)";

    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        MyUser user = this.loadMyUsersByUsername(username);
        if(user == null) {
            this.logger.debug("Query returned no results for user \'" + username + "\'");
            throw new UsernameNotFoundException(this.messages.getMessage("JdbcDaoImpl.notFound", new Object[]{username}, "Username {0} not found"), username);
        } else {
            HashSet dbAuthsSet = new HashSet();

            if(this.enableAuthorities) {
                dbAuthsSet.addAll(this.myloadGroupAuthorities(user.getUsername()));
            }

            if(this.enableGroups) {
                dbAuthsSet.addAll(this.loadGroupAuthorities(user.getUsername()));
            }

            ArrayList dbAuths = new ArrayList(dbAuthsSet);
            this.addCustomAuthorities(user.getUsername(), dbAuths);
            if(dbAuths.size() == 0) {
                this.logger.debug("User \'" + username + "\' has no authorities and will be treated as \'no t found\'");
                throw new UsernameNotFoundException(this.messages.getMessage("JdbcDaoImpl.noAuthority", new Object[]{username}, "User {0} has no GrantedAuthority"), username);
            } else {
                return this.createUserDetails(username, user, dbAuths);
            }
        }
    }

    protected MyUser loadMyUsersByUsername(String username) {
        MyUser myUser = null;
        try {
            //查询用户信息
            myUser = (MyUser) this.getJdbcTemplate().queryForObject(this.myUsersByUsernameQuery, new String[]{username}, new RowMapper() {
                public MyUser mapRow(ResultSet rs, int rowNum) throws SQLException {
                    String username = rs.getString(1);
                    String password = rs.getString(2);
                    boolean enabled = rs.getBoolean(3);
                    String phone = rs.getString(4);
                    int age = rs.getInt(5);
                    String nick = rs.getString(6);
                    long id = rs.getLong(7);
                    return new MyUser(id, username, password, phone, age, nick,Collections.EMPTY_LIST);
                }
            });
        } catch (Exception e) {
            logger.info("输入的用户名或者密码有误！！！");
        }
        return myUser;
    }

    protected UserDetails createUserDetails(String username, MyUser userFromUserQuery, List<GrantedAuthority> combinedAuthorities) {
        String returnUsername = userFromUserQuery.getUsername();
        if(!this.usernameBasedPrimaryKey) {
            returnUsername = username;
        }
        return new MyUser(userFromUserQuery.getId(),returnUsername, userFromUserQuery.getPassword(),userFromUserQuery.getPhone(), userFromUserQuery.getAge(), userFromUserQuery.getNick(), combinedAuthorities);
    }

    protected List<GrantedAuthority> myloadGroupAuthorities(String username) {
        //查询该用户的所有权限
        List<GrantedAuthority> auths = new ArrayList<GrantedAuthority>();
        try {
            List list = getJdbcTemplate().queryForList(myAuthority,username);
            if(list.size()>0){
                GrantedAuthority grantedAuthority = null;
                Iterator it = list.iterator();
                while(it.hasNext()) {
                    Map userMap = (Map) it.next();
                    grantedAuthority = new SimpleGrantedAuthority((String)userMap.get("authority"));
                    auths.add(grantedAuthority);
                }
            }
        }catch (Exception e){e.printStackTrace();}
        return auths;
/*        return this.getJdbcTemplate().query(this.groupAuthoritiesByUsernameQuery, new String[]{username}, new RowMapper() {
            public GrantedAuthority mapRow(ResultSet rs, int rowNum) throws SQLException {
                String roleName = JdbcDaoImpl.this.getRolePrefix() + rs.getString(3);
                return new SimpleGrantedAuthority(roleName);
            }
        });*/
    }
}
